package strategies

import (
	"fmt"
	"github.com/nntaoli-project/goex"
	"github.com/patrickmn/go-cache"
	"log"
	"quantization_trading/src/models"
	"quantization_trading/src/mycache"
	"quantization_trading/src/server/ws"
	"quantization_trading/src/util"
	"strings"
)

type StrategyAPI interface {

	//处理订阅价格
	HandlePrice(trade *goex.Trade)
}

type Strategy struct {
	StrategyName string
	AccountName string
	Exchange string `json:"exchange"` //交易所
	ContractType string `json:"contract_type"` //合约类型
	Symbol string `json:"symbol"`  //交易对
	Status bool //策略是否启动

	//接收订阅的价格
	SubPrice chan *goex.Trade
}

func (this Strategy)HandlePrice(trade *goex.Trade)  {
	log.Println(this.StrategyName,trade)
}




//初始化策略
func InitStrategy(){
	strategy_list := models.FindAllStrategy()
	for _,strategy :=range strategy_list{
		code := NewStrategy(strategy)
		if strategy.Status == true && code!= util.CREATE_STRATEGY_ERROR_NOT_ORDERSUB{
			StartStrategy(strategy.StrategyName,strategy.AccountName)
		}
	}
}

//创建策略
func NewStrategy(strategyConfig models.Strategy) int {
	//策略命名格式策略_用户名  例如：wildfluctuation2_hu2
	switch  {
	case strings.Contains(strings.ToLower(strategyConfig.StrategyName), "wildfluctuation"):
		_,code := NewWildFluctuation(strategyConfig)
		return code
	default:
		return util.CREATE_STRATEGY_ERROR
	}
}

//启动策略
func StartStrategy(strategyName,accountName string) int {
	switch  {
	case strings.Contains(strings.ToLower(strategyName), "wildfluctuation"):
		return StartStrategyWildFluctuation(strategyName,accountName)
	default:
		return util.NOT_STRATEGY_ERROR
	}
	return util.START_ERROR_STRATEGY
}

//停止策略
func StopStrategy(strategyName,accountName string) int {
	var sub ws.SubscribePriceStruct
	strategyKey := fmt.Sprintf("%s_%s",strategyName,accountName)
	switch  {
	case strings.Contains(strings.ToLower(strategyName), "wildfluctuation"):
		var this *StrategyWildFluctuation
		if x,ok := mycache.StrategyCache.Get(strategyKey) ;ok{
			this = x.(*StrategyWildFluctuation)
			if this.Status {
				priceKey := fmt.Sprintf("%s_%s_%s_price", this.Exchange, this.ContractType, this.Symbol)
				if x,ok := mycache.PriceCache.Get(priceKey); ok {
					sub = x.(ws.SubscribePriceStruct)
					sub.DelStrategy(strategyKey)
					this.Status = false
					// 更新缓存
					mycache.StrategyCache.Set(strategyKey,this,cache.NoExpiration)
					// 更新数据库
					models.UpdateStrategy(strategyName,accountName,this.Status)
					return util.STOP_SUSSESS_STRATEGY
				}else {
					log.Println("没有订阅该数据")
					return util.NOT_SUB_PRICE
				}
			}else {
				return util.STOP_STRATEGY_ERROR_NOT_START
			}
		}
	default:
		return util.NOT_STRATEGY_ERROR
	}
	return util.STOP_ERROR_STRATEGY
}

//  删除策略（会强制停止策略）
func DelStrategy(strategyName,accountName string) int {
	var sub ws.SubscribePriceStruct
	strategyKey := fmt.Sprintf("%s_%s",strategyName,accountName)
	switch  {
	case strings.Contains(strings.ToLower(strategyName), "wildfluctuation"):
		var this *StrategyWildFluctuation
		if x,ok := mycache.StrategyCache.Get(strategyKey) ;ok{
			this = x.(*StrategyWildFluctuation)
			priceKey := fmt.Sprintf("%s_%s_%s_price", this.Exchange, this.ContractType, this.Symbol)
			if x,ok := mycache.PriceCache.Get(priceKey); ok {
				sub = x.(ws.SubscribePriceStruct)
				sub.DelStrategy(strategyKey)
				//删除缓存
				mycache.StrategyCache.Delete(strategyKey)
				//删除数据
				models.DelStrategy(strategyName,accountName)
				return util.DEL_SUSSESS_STRATEGY
			}else {
				log.Println("没有订阅该数据")
				return util.NOT_SUB_PRICE
			}
		}
	default:
		return util.NOT_STRATEGY_ERROR
	}
	return util.DEL_ERROR_STRATEGY
}

